package com.thermofisher.dsc.amanda.common.crud.service;

import com.thermofisher.dsc.amanda.common.Query;
import com.thermofisher.dsc.amanda.model.BaseModel;
import com.thermofisher.dsc.amanda.model.response.PageResponse;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * base service
 * @author wenjie.yang on 10/29/2018.
 */
public interface BaseService<T> {

    /**
     * for create entity
     * @param entity
     * @return
     */
    T create(T entity);

    /**
     * for update entity
     * @param entity
     * @return
     */
    T update(T entity);

    /**
     * for delete entity
     * @param id
     */
    void delete(Long id);

    /**
     * for get paging entity data
     * @param query
     * @return
     */
    PageResponse getList(Query query);

  /**
   * for entity Count
   * @param query
   * @return
   */
    default int getListCount(Query query) {
        // For backward compatibility
        return 0;
    }

    /**
     * for get entity by id
     * @param id
     * @return
     */
    T getById(Long id);

    /**
     * build query Example condition
     */
    static String PECENTAGE_SYMBOL = "%";
    default Example buildDefaultAndCriteria(Query query, Class klass) {
        Example example = new Example(klass);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(query.getOrderByClause())) {
          example.setOrderByClause(query.getOrderByClause());
        }
        query.keySet().stream().forEach(key -> {
            if (key == null || key.trim().equals("")) {
                return;
            }
            Object value = query.get(key);
            if (value == null || value.toString().trim().equals("")) {
                return;
            }
            if(key.equals(Query.SELECTED)){
              return ;
            }else if (Query.isPrecise(key)) {
                if(value instanceof List){
                  criteria.andIn(Query.removePrefix(key),(List)value);
                }else{
                  criteria.andEqualTo(Query.removePrefix(key), value);
                }
            }else if(Query.isOrderBy(key)){
                example.setOrderByClause(value.toString());
            }else if (key.equals(Query.RANGE_FOUND_YEAR)){
              String[] years = value.toString().split(",");
              criteria.andBetween(key.replace(Query.RANGE_PREFIX,""),years[0],years[1]);
            }else if (key.indexOf(Query.OR_PREFIX)!=-1){
              Criteria orCriteria = example.createCriteria();
              String[] ors = key.toString().split(Query.OR_PREFIX);
              orCriteria.orLike(ors[0],"%"+value.toString()+"%").orLike(ors[1],"%"+value.toString()+"%");
              example.and(orCriteria);
            }else {
                criteria.andLike(key, PECENTAGE_SYMBOL.concat(value.toString()).concat(PECENTAGE_SYMBOL));
            }
        });
        return example;
    }

    /**
     * set createBy and createTime
     * @param dto
     * @param userId
     */
    static void populateAuditInfo(BaseModel dto, Long userId) {
        if (dto == null) {
            return;
        }
    }

    default public void createList(List<T> tlist) {
    }

    default public void deleteListByIds(List<Long> ids) {
    }

}